# frozen_string_literal: true

# 这里是多行注释
# 这里是多行注释
# 这里是多行注释

(1...10).each do |i|
  puts i # 这是单行注释
end

puts 'hello world'

a = 20
if a >= 10
  print "greater\n"
else
  print "smaller\n"
end

i = 1
while i <= 10
  if i == 10
    print i, "\n"
    break
  else
    print i, ', '
  end
  i += 1
end

10.times do |i|
  print "打印#{i + 1}次\n"
end

user = { name: '小明', age: 18, sex: '男' }
user.each do |key, value|
  puts "#{key}: #{value}"
end

# file = File.open(".\\file\\任务批量导入案例.csv") #默认是当前工程所在目录为基准，不是打开的文件所在目录为基准
# file.each_line do |line|
#   puts line
# end
# file.close

str1 = 'foo'
str2 = str1
str3 = 'f' + 'o' + 'o'
str4 = str1.dup
puts str1.equal?(str2)
puts str1.equal?(str3)
puts str1.equal?(str4)

def sum_for
  total = 0
  for i in 1..5
    total += i
  end
  total
end

puts sum_for

total = 0
i = 1
while total < 50
  total += i
  i += 1
end
puts "sum = #{total}, i = #{i}"

def sum_each
  total = 0
  (1..5).each do |i|
    total += i
  end
  total
end

puts sum_each

def max(a, b)
  if a > b
    a
  else
    b
  end
end

p max(10, 15)
p print("hh\t")

def myloop
  yield while true
end

num = 1
myloop do
  puts "num = #{num}"
  break if num > 10

  num *= 2
end

# 使用关键字参数的函数，关键字参数没有顺序之分
def area(x: 0, y: 0, z: 0)
  xy = x * y
  yz = y * z
  zx = z * x
  (xy + yz + zx) * 2
end

puts area(x: 3, y: 4, z: 5)
arg1 = { x: 4, y: 5, z: 6 }
# hash转换为关键字参数，采用**hash方式
puts area(**arg1)

class HelloWorld
  Version = '1.0'
  attr_accessor :name

  @@count = 0

  def initialize(name = 'Ruby')
    @name = name
    @@count += 1
  end

  def greet
    puts "hello #{name}"
  end

  class << self # 单例类定义
    # 这里定义类方法，单例方法，可以不带前缀self或者HelloWorld
    def count
      @@count
    end
  end
end

bob = HelloWorld.new('Bob')
bob.greet
alice = HelloWorld.new('Alice')
alice.greet
ruby = HelloWorld.new
ruby.greet
puts HelloWorld.count
puts HelloWorld::Version

class AccTest
  def initialize
    puts 'initialized'
  end

  public

  def pub
    puts 'public method'
    pri
    pro
  end

  private

  def pri
    puts 'private method'
  end

  protected

  def pro
    puts 'protected method'
  end
end

acc = AccTest.new
acc.pub
# acc.pro
# acc.pri

class SubAccTest < AccTest
  def pub2
    puts 'sub public method'
    pro
    pri
  end
end

puts '-' * 30
sub_acc = SubAccTest.new
sub_acc.pub
sub_acc.pub2
# sub_acc.pro
# sub_acc.pri

# 组合比较运算符 <=>
def composition_compare
  puts 1 <=> 2
  puts 1 <=> 1
  puts 2 <=> 1
end

composition_compare

class Point
  attr_accessor :x, :y

  def initialize(x = 0, y = 0)
    @x = x
    @y = y
  end

  def inspect
    "(#{x}, #{y})"
  end

  def +(other)
    self.class.new(x + other.x, y + other.y)
  end

  def -(other)
    self.class.new(x - other.x, y - other.y)
  end

  def +@
    dup
  end

  def -@
    self.class.new(-x, -y)
  end

  # 坐标翻转90度
  def ~@
    self.class.new(-y, x)
  end

  def [](index)
    case index
    when 0
      x
    when 1
      y
    else
      raise ArgumentError, "out of range `#{index}`"
    end
  end

  def []=(index, value)
    case index
    when 0
      self.x = value
    when 1
      self.y = value
    else
      raise ArgumentError, "out of range `#{index}'"
    end
  end
end

p1 = Point.new
p p1
p2 = Point.new(1, 2)
p p2
p3 = Point.new(2, 1)
p p2 + p3
p p3 - p2
p(-p2)
p ~p2
puts p3[0]
puts p3[1]
# puts p3[2]

# File.open("./file/任务批量导入案例.csv") do |file|
#   file.each_line do |line|
#     print line
#   end
# end

ary = %w[
  Ruby is a open source programming language with a focus on simplicity and productivity.
  It has an elegant syntax that is natural to read and easy to write
]
call_num = 0
sorted = ary.sort do |a, b|
  call_num += 1
  a.length <=> b.length
end
puts "排序结果：#{sorted}"
puts "数组元素个数：#{ary.length}"
puts "调用块的次数：#{call_num}"

call_num = 0
sorted = ary.sort_by do |item|
  call_num += 1
  item.length
end
puts "排序结果：#{sorted}"
puts "数组元素个数：#{ary.length}"
puts "调用块的次数：#{call_num}"
